package com.fz.us.oa.web.controller.com;

import com.fz.us.admin.base.bean.BaseEnumManager;
import com.fz.us.admin.base.bean.jqgrid.JqGridFilter;
import com.fz.us.admin.base.bean.jqgrid.JqGridPager;
import com.fz.us.admin.base.bean.search.SearchEnum;
import com.fz.us.admin.base.bean.search.order.Order;
import com.fz.us.admin.base.bean.search.result.SearchResultPaging;
import com.fz.us.admin.base.bean.search.rule.Rule;
import com.fz.us.admin.base.bean.search.rule.RuleHelper;
import com.fz.us.admin.base.utils.DataUtil;
import com.fz.us.admin.company.bean.FlowEnum;
import com.fz.us.admin.company.entity.*;
import com.fz.us.admin.company.service.*;
import com.fz.us.admin.dict.entity.DictItem;
import com.fz.us.admin.dict.service.DictItemService;
import com.fz.us.oa.core.entity.com.Outfile;
import com.fz.us.oa.core.entity.common.FileManage;
import com.fz.us.oa.core.service.com.OutfileService;
import com.fz.us.oa.core.service.common.FileManagerService;
import com.fz.us.oa.web.controller.BaseController;
import com.fz.us.oa.web.shiro.bind.annotation.CurrentUser;
import com.fz.us.oa.web.spring.bind.annotation.RequestJsonParam;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by ZhuChunXiao on 2017/7/24.
 */
@Controller
@RequestMapping(value = "/com/outfile")
public class OutfileController extends BaseController {
    private static final long serialVersionUID = -1264156364414930282L;

    @Autowired
    private OutfileService outfileService;
    @Autowired
    private DictItemService dictItemService;
    @Autowired
    private UserService userService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private DutyService dutyService;
    @Autowired
    private TaskEntityService taskEntityService;
    @Autowired
    private FileManagerService fileManagerService;
    @Autowired
    private RemindService remindService;


    /**
     * 新建，编辑页面
     */
    @RequestMapping(value = "input", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String input(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record) {
        ArrayList<DictItem> dictItems = getDictItems(user,"outfileType");
        if (StringUtils.isNotEmpty(keyId)){
            Outfile outfile=outfileService.get(keyId);
            String fileId ="";
            if(outfile.getFile() != null && outfile.getFile().size()>0){
                for(FileManage f:outfile.getFile()){
                    fileId+=f.getId()+",";
                }
            }
            model.addAttribute("fileId", fileId);
            model.addAttribute("keyId", keyId);
            model.addAttribute("outfile", outfile);
        }
        model.addAttribute("dictItems", dictItems);
        model.addAttribute("user", user);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        return "/com/outfile_input";
    }

    /**
     * 只读页面
     */
    @RequestMapping(value = "read", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String read(@CurrentUser User user, Model model,String keyId,String draft,String index,String todo,String remind,String record) {
        if(StringUtils.isNotEmpty(keyId)) {
            String fileId ="";
            Outfile outfile=outfileService.get(keyId);
            if(outfile.getFile() != null && outfile.getFile().size()>0){
                for(FileManage f:outfile.getFile()){
                    fileId+=f.getId()+",";
                }
            }
            if(!outfile.getProcessState().name().equals("Destroy")&&!outfile.getProcessState().name().equals("Finished")){
                TaskEntity taskEntity = taskEntityService.getInfoByKeyId(keyId);
                int stepNo = taskEntity.getStepNo();

                String isEdit =  isEdit(keyId);
                model.addAttribute("stepNo", stepNo);
                model.addAttribute("isEdit", isEdit);
            }
            model.addAttribute("outfile", outfile);
            model.addAttribute("fileId", fileId);
        }

        model.addAttribute("keyId", keyId);
        model.addAttribute("draft", draft);
        model.addAttribute("index", index);
        model.addAttribute("todo", todo);
        model.addAttribute("remind", remind);
        model.addAttribute("record", record);
        return "/com/outfile_read";
    }

    /**
     * 历史文档的只读页面
     */
    @RequestMapping(value = "readhistory/{keyId}", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String readhistory(@CurrentUser User user, Model model,
                              @PathVariable String keyId) {

        String fileId ="";
        Outfile outfile = outfileService.get(keyId);
        if(outfile.getFile() != null && outfile.getFile().size()>0){
            for(FileManage f:outfile.getFile()){
                fileId+=f.getId()+",";
            }
        }
        model.addAttribute("fileId", fileId);
        model.addAttribute("keyId", keyId);
        model.addAttribute("outfile",outfile);
        model.addAttribute("user",user);

        return "/com/outfile_readhistory";
    }

    /**
     * 保存Model数据
     */
    private Outfile saveModel(User user, String keyId, String dictItemId, String fileNo, String name,String datPulished,
                              String noticeType, String deptIds, String userIds, String viewerIds,String fileIds) {

        Outfile outfile = null;
        if (StringUtils.isBlank(keyId)) {
            outfile = new Outfile();
            outfile.setCreater(user);
            outfile.setCompany(user.getCompany());
        } else {
            outfile = outfileService.get(keyId);
        }

        if (StringUtils.isNotBlank(dictItemId)) {
            DictItem dictItem = dictItemService.get(dictItemId);
            outfile.setDictItem(dictItem);
        }

        if (StringUtils.isNotBlank(fileNo)) {
            outfile.setFileNo(fileNo);
        }

        if (StringUtils.isNotBlank(name)) {
            outfile.setName(name);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (StringUtils.isNotBlank(datPulished)) {
            try {
                outfile.setDatPulished(sdf.parse(datPulished));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        if (StringUtils.isNotBlank(noticeType)) {
            int nt = Integer.valueOf(noticeType);
            if(nt == 1){
                if(StringUtils.isNotBlank(deptIds)){
                    String[] depts = StringUtils.split(deptIds,",");
                    HashSet<Department> objs = new HashSet<Department>();
                    for (String id : depts) {
                        Department dept = departmentService.get(id);
                        objs.add(dept);
                    }
                    outfile.setNoticeDepartments(objs);
                }
            } else if(nt == 2){
                if (StringUtils.isNotBlank(userIds)) {
                    String[] uids = StringUtils.split(userIds,",");
                    HashSet<User> users = new HashSet<User>();
                    for (String uid : uids) {
                        User u = userService.get(uid);
                        users.add(u);
                    }
                    outfile.setNoticeUsers(users);
                }
            }
            outfile.setNoticeType(nt);
        }


        if (StringUtils.isNotBlank(viewerIds)) {
            String[] uids = StringUtils.split(viewerIds, ",");
            HashSet<User> users = new HashSet<User>();
            for (String uid : uids) {
                User u = userService.get(uid);
                users.add(u);
            }
            outfile.setViewers(users);
            outfile.setViewerIds(viewerIds);
        }

        List<FileManage> fileManageList = Lists.newArrayList();
        if(StringUtils.isNotEmpty(fileIds)){
            for(String f:fileIds.split(",")){
                fileManageList.add(fileManagerService.get(f.trim()));
            }
        }
        outfile.setFile(fileManageList);

        if (outfile.getForm() == null) {
            outfile.setForm("发文申请表");
        }

        return outfile;
    }

    /**
     * 保存操作
     */
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public Object save(@CurrentUser User user,
                       @RequestParam(required = false) String keyId,
                       String dictItemId, String fileNo, String name,String datPulished,
                       String noticeType, String deptIds, String userIds, String viewerIds,String fileIds){

        Map<String,Object> rMap=new HashMap<String,Object>();
        Outfile outfile = saveModel(user, keyId, dictItemId, fileNo, name, datPulished, noticeType, deptIds, userIds, viewerIds, fileIds);
        outfile.setTxtStatus("草稿");
        if(StringUtils.isNotEmpty(keyId)){
            outfileService.update(outfile);
            rMap.put("message", "更新成功");
        } else {
            outfileService.save(outfile, "com.fz.us.oa.core.entity.com.Outfile");
            rMap.put("message","保存成功");
        }
        rMap.put("state", "1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    /**
     *提交操作
     */
    @RequestMapping(value = "commit", method = RequestMethod.POST)
    public Object commit(@CurrentUser User user,
                         @RequestParam(required = false) String keyId,
                         String dictItemId, String fileNo, String name,String datPulished,
                         String noticeType, String deptIds, String userIds, String viewerIds, String fileIds, String curDutyId, String comment){

        Map<String,Object> rMap=new HashMap<String,Object>();
        Outfile outfile = saveModel(user,keyId,dictItemId,fileNo,name,datPulished,noticeType,deptIds,userIds,viewerIds,fileIds);
        outfile.setTxtStatus("流转中");

        if (StringUtils.isNotEmpty(keyId)) {
            outfileService.approve(outfile, dutyService.get(curDutyId), comment);
        } else {
            outfileService.commit(outfile, "com.fz.us.oa.core.entity.com.Outfile", dutyService.get(curDutyId));
        }

        if(outfile.getProcessState().name().equals("Finished")){
            doFinished(outfile);
        }

        rMap.put("message","提交成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    //审批
    @RequestMapping(value = "approve", method = RequestMethod.POST)
    public Object approve(@CurrentUser User user, String keyId,  String curDutyId, String comment){
        Map<String,Object> rMap=new HashMap<String,Object>();
        Outfile outfile=outfileService.get(keyId);
        outfileService.approve(outfile, dutyService.get(curDutyId), comment);

        if(outfile.getProcessState().name().equals("Finished")){
            doFinished(outfile);
        }

        rMap.put("message","提交成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    public void doFinished(Outfile outfile){
        outfile.setTxtStatus("已归档");
        outfileService.update(outfile);

        //发送提醒
        if(outfile.getNoticeType()==0){
            Map<String, Object> map=new HashMap<String, Object>();
            map.put("state",BaseEnumManager.StateEnum.Enable);
            List<User> userList=userService.getList(map);
            for(User user1:userList){
                Remind remind = new Remind();
                remind.setUser(user1);
                remind.setBussinessKey("outfile");
                remind.setKeyId(outfile.getId());
                remind.setContent("您有一份发文需要查看，请查看");
                remindService.save(remind);
            }
            System.out.println("发送全体，给"+userList.size()+"人发送了通知");
        }else if(outfile.getNoticeType()==1){
            Set<User> userSet=new HashSet<User>();
            for(Department dept:outfile.getNoticeDepartments()){
                Set<Power> powerSet=dept.getPowerSet();
                for(Power power:powerSet){
                    List<User> usersList=dutyService.getPersons(dept,power.getPost());
                    for(User user1:usersList){
                        userSet.add(user1);
                    }
                }
            }
            for(User user1:userSet){
                Remind remind = new Remind();
                remind.setUser(user1);
                remind.setBussinessKey("outfile");
                remind.setKeyId(outfile.getId());
                remind.setContent("您有一份发文需要查看，请查看");
                remindService.save(remind);
            }
            System.out.println("发送部门，给"+userSet.size()+"人发送了通知");
        }else if(outfile.getNoticeType()==2){
            for(User user1:outfile.getNoticeUsers()){
                Remind remind = new Remind();
                remind.setUser(user1);
                remind.setBussinessKey("outfile");
                remind.setKeyId(outfile.getId());
                remind.setContent("您有一份发文需要查看，请查看");
                remindService.save(remind);
            }
            System.out.println("发送个人，给"+outfile.getNoticeUsers().size() +"人发送了通知");
        }
    }

    /**
     * 退回
     * @return
     */
    @RequestMapping(value = "back", method = RequestMethod.POST)
    public Object back(@CurrentUser User user, String keyId,String curDutyId, String comment) {
        if (StringUtils.isNotEmpty(keyId)) {
            Outfile outfile=outfileService.get(keyId);
            outfileService.back(outfile, dutyService.get(curDutyId), comment);
        }
        Map<String,Object> rMap=new HashMap<String,Object>();
        rMap.put("message","退回成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }
    /**
     * 否决
     * @return
     */
    @RequestMapping(value = "deny", method = RequestMethod.POST)
    public Object deny(@CurrentUser User user, String keyId,String curDutyId, String comment) {
        if (StringUtils.isNotEmpty(keyId)) {
            Outfile outfile=outfileService.get(keyId);
            outfileService.deny(outfile, dutyService.get(curDutyId), comment);
        }
        Map<String,Object> rMap=new HashMap<String,Object>();
        rMap.put("message","否决成功");
        rMap.put("state","1");
        rMap.put("keyId", keyId);
        return ajaxJson(rMap);
    }

    /**
     * 列表
     */
    @RequestMapping(value = "list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> list(@CurrentUser User user,
                                    @RequestParam(required = false) String updateUnid,
                                    JqGridPager pager,
                                    @RequestJsonParam(value = "filters", required = false) JqGridFilter filters) {
        Company company = user.getCompany();
        // 排序
        Order order =  Order.order("createTime", SearchEnum.OrderType.desc);
        SearchResultPaging searchResult = null;

        List<Rule> rules = new ArrayList<Rule>();
        rules.add(RuleHelper.eq("company", company));   // 所在的公司
        rules.add(RuleHelper.eq("state", BaseEnumManager.StateEnum.Enable));    // 文档为有效的
        rules.add(RuleHelper.or(
                RuleHelper.eq("processState", FlowEnum.ProcessState.Finished),
                RuleHelper.eq("processState", FlowEnum.ProcessState.Running),
                RuleHelper.eq("processState", FlowEnum.ProcessState.Destroy)
        ));
        if (updateUnid!=null && !updateUnid.isEmpty()) {
            rules.add(RuleHelper.eq("updateUnid", updateUnid));
            rules.add(RuleHelper.eq("txtStatus", "历史"));
        } else {
            rules.add(RuleHelper.ne("txtStatus", "历史"));
        }

//        Map<String,Object> params = new HashMap<String,Object>();
//        params.put("company", company);
//        params.put("state", new BaseEnumManager.StateEnum[]{BaseEnumManager.StateEnum.Enable, BaseEnumManager.StateEnum.Delete});
//
//        //所有单子
//        searchResult = outfileService.paging(null,rules,order,
//                "com.fz.us.oa.core.entity.com.Outfile",
//                new FlowEnum.ProcessState []{FlowEnum.ProcessState.Running, FlowEnum.ProcessState.Backed, FlowEnum.ProcessState.Finished}, params);
        searchResult = outfileService.findPagingBySearch(null,rules,order);

        List<Outfile> outfileList = searchResult.getList();
        ArrayList<Map<String, Object>> dataRows = new ArrayList<Map<String, Object>>();
        Map<String, Object> data = new HashMap<String, Object>();
        Map<String,Object> rMap;

        for(Outfile outfile: outfileList){
            rMap = new HashMap<String, Object>();
            rMap.put("id", StringUtils.isEmpty(outfile.getId())?"":outfile.getId());
            rMap.put("name", StringUtils.isEmpty(outfile.getName())?"":outfile.getName());
            rMap.put("fileNo", StringUtils.isEmpty(outfile.getFileNo())?"":outfile.getFileNo());

            if (outfile.getDictItem() != null) {
                DictItem sealDictItem = outfile.getDictItem();
                rMap.put("dictItemId", sealDictItem.getId());
                String definedName = dictItemService.getDefinedName(outfile.getCompany().getId(), sealDictItem.getId());
                rMap.put("dictItemName", StringUtils.isEmpty(definedName)?sealDictItem.getName():definedName);
            }

            rMap.put("datPulished", outfile.getDatPulished()==null?"": DataUtil.DateToString(outfile.getDatPulished()));
            rMap.put("numRevise", "第" + outfile.getNumRevise() + "次");
//            rMap.put("txtStatus",outfile.getProcessState().value());
            rMap.put("txtStatus", outfile.getTxtStatus());
//        rMap.put("creater", entity.getCreater()==null?"": entity.getCreater().getName());
//        rMap.put("processStateName", entity.getProcessState()==null?"": entity.getProcessState().value());
//        rMap.put("createTime", entity.getCreateTime()==null?"": DataUtil.DateTimeToString(entity.getCreateTime()));
            dataRows.add(rMap);
        }

        data.put("dataRows", dataRows);
        data.put("page", searchResult.getPageNumber());
        data.put("rows", searchResult.getPageSize());
        data.put("records", searchResult.getTotalCount());
        data.put("total", searchResult.getPageCount());
        return data;
    }

    /**
     * 完成修改操作
     */
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public Object update(@CurrentUser User user,
                         @RequestParam(required = false) String keyId, String dictItemId, String fileNo, String name,String datPulished,
                         String noticeType, String deptIds, String userIds, String viewerIds, String fileIds) throws ParseException {

        int numRevise = 0;
        String unid = "";
        if (StringUtils.isNotBlank(keyId)) {
            Outfile outfileOld = outfileService.get(keyId);
            outfileOld.setNumStatus(-1);
            outfileOld.setTxtStatus("历史");
            outfileOld.setProcessState(FlowEnum.ProcessState.Destroy);
            outfileOld.setDateUpdate(new Date());
            if (outfileOld.getUpdateUnid() == null) {
                unid = keyId;
                outfileOld.setUpdateUnid(keyId);
            } else {
                unid = outfileOld.getUpdateUnid();
            }
            numRevise = outfileOld.getNumRevise();
            outfileService.saveEntity(outfileOld);
        }

        Outfile outfile = saveModel(user,"",dictItemId,fileNo,name,datPulished,noticeType,deptIds,userIds,viewerIds,fileIds);

        if(outfile == null){
            return ajaxJson(resultService.fail("保存业务数据失败！"));
        }

        outfile.setNumRevise(numRevise + 1);
        outfile.setDateApply(new Date());
        outfile.setNumStatus(1);
        outfile.setProcessState(FlowEnum.ProcessState.Finished);
        outfile.setTxtStatus("已归档");

        outfile.setUpdateUnid(unid);
        return ajaxJson(outfileService.saveEntity(outfile));
    }

    /**
     * 失效
     */
    @RequestMapping(value = "invalid/{keyId}", method = RequestMethod.POST)
    public Object saveDialogReturn(@CurrentUser User user,@PathVariable String keyId) throws ParseException {
        Outfile outfile = outfileService.get(keyId);

        if (outfile==null) {
            return resultService.fail("对应的业务数据已丢失！");
        }

        outfile.setTxtStatus("已失效");
        return ajaxJson(outfileService.saveEntity(outfile));
    }

}
